#include "wxstoolbar.h"
#include "wxstoolbaritem.h"
#include "wxstoolbareditor.h"
#include "../wxsitemresdata.h"
#include <wx/toolbar.h>
#include "scrollingdialog.h"

namespace {
  wxsRegisterItem<wxsToolBar> Reg( _T( "ToolBar" ), _T( "ToolBar" ), wxsTTool, _T( "工具" ), 10 );
  class ToolBarEditorDialog: public wxScrollingDialog {
    public:
      wxsToolBarEditor* Editor;
      ToolBarEditorDialog( wxsToolBar* ToolBar ):
        wxScrollingDialog( 0, -1, _T( "ToolBar editor" ), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) {
        wxBoxSizer* Sizer = new wxBoxSizer( wxVERTICAL );
        Sizer->Add( Editor = new wxsToolBarEditor( this, ToolBar ), 1, wxEXPAND, 0 );
        Sizer->Add( CreateButtonSizer( wxOK | wxCANCEL ), 0, wxEXPAND, 15 );
        SetSizer( Sizer );
        Sizer->SetSizeHints( this );
        PlaceWindow( this, pdlCentre, true );
      }
      void OnOK( M_Code_unused wxCommandEvent& event ) {
        Editor->ApplyChanges();
        EndModal( wxID_OK );
      }
      DECLARE_EVENT_TABLE()
  };

  BEGIN_EVENT_TABLE( ToolBarEditorDialog, wxScrollingDialog )
    EVT_BUTTON( wxID_OK, ToolBarEditorDialog::OnOK )
  END_EVENT_TABLE()


  WXS_ST_BEGIN( wxsToolBarStyles, _T( "wxTB_HORIZONTAL|wxNO_BORDER" ) )
  WXS_ST( wxTB_FLAT )
  WXS_ST( wxTB_DOCKABLE )
  WXS_ST( wxTB_VERTICAL )
  WXS_ST( wxTB_HORIZONTAL )
  WXS_ST( wxTB_TEXT )
  WXS_ST( wxTB_NOICONS )
  WXS_ST( wxTB_NODIVIDER )
  WXS_ST( wxTB_NOALIGN )
  WXS_ST( wxTB_HORZ_LAYOUT )
  WXS_ST( wxTB_HORZ_TEXT )
  WXS_ST( wxTB_TOP )
  WXS_ST( wxTB_LEFT )
  WXS_ST( wxTB_RIGHT )
  WXS_ST( wxTB_BOTTOM )
  WXS_ST_DEFAULTS()
  WXS_ST_END()
}

wxsToolBar::wxsToolBar( wxsItemResData* Data ):
  wxsTool(
    Data,
    &Reg.Info,
    0,
    wxsToolBarStyles,
    flVariable | flId | flSubclass | flExtraCode ),
  m_Packing( -1 ),
  m_Separation( -1 ) {
  m_BitmapSize.IsDefault = true;
  m_BitmapSize.X = 16;
  m_BitmapSize.Y = 16;
  m_BitmapSize.DialogUnits = false;
  m_Margins.IsDefault = true;
  m_Margins.X = 16;
  m_Margins.Y = 16;
  m_Margins.DialogUnits = false;
}

void wxsToolBar::OnBuildCreatingCode() {
  switch( GetLanguage() ) {
  case wxsCPP:
    AddHeader( _T( "<wx/toolbar.h>" ), GetInfo().ClassName, hfInPCH );
    if( GetChildCount() ) {
      Codef( _T( "%C(%W, %I, %P, %S, %T, %N);\n" ) );
      if( !m_BitmapSize.IsDefault ) {
        Codef( _T( "%ASetToolBitmapSize(%z);\n" ), &m_BitmapSize );
      }
      if( !m_Margins.IsDefault ) {
        Codef( _T( "%ASetMargins(%<);\n" ), &m_Margins );
      }
      if( m_Packing >= 0 ) {
        Codef( _T( "%ASetToolPacking(%d);\n" ), m_Packing );
      }
      if( m_Separation >= 0 ) {
        Codef( _T( "%ASetToolSeparation(%d);\n" ), m_Separation );
      }
      for( int i = 0; i < GetChildCount(); i++ ) {
        wxsItem* Child = GetChild( i );
        Child->BuildCode( GetCoderContext() );
        if( Child->GetClassName() != _T( "wxToolBarToolBase" ) ) {
          Codef( _T( "%AAddControl(%o);\n" ), i );
        }
      }
      Codef( _T( "%ARealize();\n" ) );
      BuildSetupWindowCode();
      if( !GetParent() && GetResourceData()->GetClassType() == _T( "wxFrame" ) ) {
        Codef( _T( "SetToolBar(%O);\n" ) );
      }
    }
    break;
  case wxsUnknownLanguage:
  default:
    wxsCodeMarks::Unknown( _T( "wxsToolBar::OnBuildCreatingCode" ), GetLanguage() );
  }
}

void wxsToolBar::OnEnumToolProperties( M_Code_unused long Flags ) {
  WXS_SIZE( wxsToolBar, m_BitmapSize, _T( "Use Bitmap size" ), _T( "  Bitmapwidth" ), _T( "  Bitmapheight" ), _T( "  Bmp in Dialog Units" ), _T( "bitmapsize" ) );
  WXS_SIZE( wxsToolBar, m_Margins, _T( "Use Margins" ), _T( "  Marginwidth" ), _T( "  MarginhHeight" ), _T( "  Margin in Dialog Units " ), _T( "margins" ) );
  WXS_LONG( wxsToolBar, m_Packing, _T( "Packing" ), _T( "packing" ), -1 );
  WXS_LONG( wxsToolBar, m_Separation, _T( "Separation" ), _T( "separation" ), -1 );
}

bool wxsToolBar::OnCanAddToResource( wxsItemResData* Data, bool ShowMessage ) {
  if( Data->GetClassType() != _T( "wxFrame" ) ) {
    if( ShowMessage ) {
      msging( _T( "wxToolBar can be added to wxFrame only" ) );
    }
    return false;
  }
  for( int i = 0; i < Data->GetToolsCount(); i++ ) {
    if( Data->GetTool( i )->GetClassName() == _T( "wxToolBar" ) ) {
      if( ShowMessage ) {
        msging( _T( "Can not add two or more wxToolBar classes\ninto one wxFrame" ) );
      }
      return false;
    }
  }
  return true;
}

bool wxsToolBar::OnCanAddChild( wxsItem* Item, bool ShowMessage ) {
  if( Item->GetType() == wxsTContainer ) {
    wxString ClassName = Item->GetClassName();
    if( ClassName == _T( "wxPanel" ) ||
        ClassName == _T( "wxDialog" ) ||
        ClassName == _T( "wxScrollingDialog" ) ||
        ClassName == _T( "wxFrame" ) ) {
      if( ShowMessage ) {
        msging( _T( "Only wxControl-derived classes can be added into wxToolBar" ) );
      }
      return false;
    }
  } else if( Item->GetType() == wxsTSizer ) {
    if( ShowMessage ) {
      msging( _T( "Cannot add sizers into wxToolBar" ) );
    }
    return false;
  } else if( Item->GetType() == wxsTSpacer ) {
    if( ShowMessage ) {
      msging( _T( "Can not add spacer into wxToolBar" ) );
    }
    return false;
  } else if( Item->GetType() == wxsTTool ) {
    if( Item->GetClassName() != _T( "wxToolBarToolBase" ) ) {
      if( ShowMessage ) {
        msging( _T( "Invalid item added into wxToolBar" ) );
      }
      return false;
    }
  }
  return true;
}

bool wxsToolBar::OnMouseDClick( M_Code_unused wxWindow* Preview, M_Code_unused int PosX, M_Code_unused int PosY ) {
  ToolBarEditorDialog Dlg( this );
  Dlg.ShowModal();
  return false;
}

bool wxsToolBar::OnXmlReadChild( TiXmlElement* Elem, bool IsXRC, bool IsExtra ) {
  if( IsXRC ) {
    wxString ClassName = cbC2U( Elem->Attribute( "class" ) );
    if( ClassName == _T( "separator" ) ) {
      wxsToolBarItem* Child = new wxsToolBarItem( GetResourceData(), true );
      AddChild( Child );
      return Child->XmlRead( Elem, IsXRC, IsExtra );
    }
    if( ClassName == _T( "tool" ) ) {
      wxsToolBarItem* Child = new wxsToolBarItem( GetResourceData(), false );
      AddChild( Child );
      return Child->XmlRead( Elem, IsXRC, IsExtra );
    }
  }
  return wxsParent::OnXmlReadChild( Elem, IsXRC, IsExtra );
}
